
# $Id: Cluster.pm 98 2013-03-26 02:22:26Z chengxin.cai $

use strict;

package Provision::Cluster;

use Provision::Object;
use base 'Provision::Object';

use Sys::Hostname;

use config ':all';
use instance ':all';
use bright ':all';

use Provision::Utils qw( performStep );
use Provision::User;
use Provision::Instance;

my $script_loc =  $nvpath . '/instance';

my @provisionSteps = (
    {
        title => 'Create instance configuration',
        cmd   => $script_loc . '/instconfig',
        args  => '--init',
    },
    {
        title => 'Create instances',
        code  => sub {
            my ($id, $test) = @_;

            my @inst_idlist = get_all_instance_ids();
            for my $inst_id ( @inst_idlist ) {
                my $instance = Provision::Instance->new($inst_id);

                my $ret = $instance->create($test);

                return $ret if ($ret != 0);
            }
            return config::OK;
        },
    },
    {
        title => 'Record version',
        cmd   => $script_loc . '/record_version',
        args  => '--full',
    },
);

my @undoSteps = (
    {
        title => 'Unmount databases and mirrors',
    },
    {
        title => 'Unmount /designs/seaquest',
    },
    {
        title => 'Remove /home/lunmgr/*',
        code  => sub {
            my ($id, $test) = @_;
            return runCmdNoCheck( '/bin/rm -rf /home/lunmgr/*', $test);
        },

    },
    {
        title => 'Replace shorewall',
        code  => sub {
            my ($id, $test) = @_;
            return runCmdNoCheck( '/bin/mv /etc/shorewall/rulesSAVE'
                                . ' /etc/shorewall/rules', $test );
        },
    },
    {
        title => 'Remove database dirs',
        code  => sub {
            my ($id, $test) = @_;

            my $configtype = get_instance_configtype();

            return config::OK if ($configtype eq 'sliced');

            my $ret = runCmdNoCheck( 'pdsh -a /bin/rm -rf /database /databasem',
                                     $test );
            return $ret if ($ret != config::OK);
            
            my @images = get_image_names();
            for my $image ( @images ) {
                $ret = runCmdNoCheck( "/bin/rm -rf /cm/images/$image/database"
                                       . " /cm/images/$image/databasem",
                                       $test );
                return $ret if ($ret != config::OK);
            }

            return runCmdNoCheck( $nvpath . '/bin/updateexcludelist -r'
                    . ' -l /database/*,/databasem/*', $test );

        },
    },
    {
        title => 'ReplaceFstab',
        code  => sub {
            my ($id, $test) = @_;
            return runCmdNoCheck( '/bin/mv /etc/fstab_PREINSTCONFIG /etc/fstab',
                                  $test );
        },
    },
    {
        title => 'ReplaceRclocal',
        code  => sub {
            my ($id, $test) = @_;

            my $configtype = get_instance_configtype();

            return config::OK if ($configtype eq 'sliced');

            my @images = get_image_names();
            for my $image ( @images ) {
                my $ret = runCmdNoCheck( "/bin/mv"
                                       . " /cm/images/$image/etc/rc.local.ORIG"
                                       . " /cm/images/$image/etc/rc.local", 
                                       $test );
                return $ret if ($ret != config::OK);
            }

            return runCmdNoCheck( "pdcp -a /cm/images/$images[0]/etc/rc.local"
                                . "/etc/rc.local", $test );
        },
    },
    {
        title => 'Remove dont_delete_me',
        code  => sub {
            my ($id, $test) = @_;
            return runCmdNoCheck( '/bin/rm -rf /home/done_delete_me', $test);
        },
    },
    {
        title => 'Rename instance conf',
    },
    {
        title => 'Unlink instance version',
    },
    {
        title => 'Remove instance status',
        code  => sub {
            my ($id, $test) = @_;
            return runCmdNoCheck( "/bin/rm -rf $script_loc/status/*", 
                                  $test );
        },
    },
);

sub new {
    my ($proto, $id) = @_;
    my $class = ref $proto || $proto;

    return $class->SUPER::new( hostname() );

}

sub create {
    my ($self, $test) = @_;

    return $self->SUPER::create( \@provisionSteps, $test );

}

sub delete {
    my ($self, $test) = @_;

    return $self->SUPER::delete( \@undoSteps, $test );

}

sub add_user {
    my ($self, $squser, $test) = @_;

    my $configtype = get_config_type();

    if ($configtype eq 'sliced') {
        logErrorDie('Cannot add a user to a sliced cluster');
    }

    if (cm_IsValidUser($squser)) {
        logErrorDie("user $squser already exist, cannot add it again");
    }

    performStep( $self, { title => 'Update instance configuration',
                          cmd   => $script_loc . '/instconfig',
                          args  => "--add --squser=$squser"
                        }, $test );

    my $user = Provision::User->new($squser);

    return $user->create($test);
}

1;

